﻿using System.Collections.Generic;
using System.IO;
using PSE.Deployment.Engine.Interfaces;
using PSE.Deployment.SetupBase.Configuration;

namespace PSE.Deployment.SetupBase.Steps
{
    public class CopySetupFiles : SetupStep<Configuration.Actions.Copy>
    {
        public CopySetupFiles(IStepGroup parent, Group group, Configuration.Actions.Copy action, Parameter.Enums.SetupMode setupMode)
            : base(parent, group, action, setupMode)
        {
            this.ResetProgress();
        }

        public override void Execute()
        {
            this.ResetProgress();

            if (this.SetupMode == Parameter.Enums.SetupMode.Install)
            {
                CopyFiles();
            }
            else if (this.SetupMode == Parameter.Enums.SetupMode.Uninstall)
            {
                UninstallArtefacts();
            }
        }

        public override void Undo()
        {
            if (this.SetupMode == Parameter.Enums.SetupMode.Install)
            {
                UninstallArtefacts();
            }
        }

        private void ResetProgress()
        {
            string path;

            if (Directory.Exists(SetupMainFactory.GetInstance().Parameter.InstalationSource))
                path = SetupMainFactory.GetInstance().Parameter.InstalationSource;
            else
            {
                path = Path.Combine(SetupMainFactory.GetInstance().Parameter.InstallationPath, SetupMainFactory.GetInstance().Parameter.SetupConfiguration.SystemInfo.Id);
                path = Path.Combine(path, "Setup-v" + SetupMainFactory.GetInstance().Parameter.SetupConfiguration.SystemInfo.Version.Major);
            }

            int count = 0;

            if (Directory.Exists(path))
            {
                count += Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly).Length;
            }

            if (Directory.Exists(Path.Combine(path, "Guides")))
            {
                count += Directory.GetFiles(Path.Combine(path, "Guides"), "*.*", SearchOption.AllDirectories).Length;
            }

            this.ResetProgress(count);            
        }

        private void CopyFiles()
        {
            string sourceFolderSetup = SetupMainFactory.GetInstance().Parameter.InstalationSource;
            string destinationFolderSetup = Path.Combine(SetupMainFactory.GetInstance().Parameter.InstallationPath, SetupMainFactory.GetInstance().Parameter.SetupConfiguration.SystemInfo.Id);
            destinationFolderSetup = Path.Combine(destinationFolderSetup, "Setup-v" + SetupMainFactory.GetInstance().Parameter.SetupConfiguration.SystemInfo.Version.Major);

            if (Directory.Exists(sourceFolderSetup))
            {
                CopyFiles(sourceFolderSetup, destinationFolderSetup, Directory.GetFiles(sourceFolderSetup, "*.*", SearchOption.TopDirectoryOnly));
            }

            string sourceFolderGuides = Path.Combine(SetupMainFactory.GetInstance().Parameter.InstalationSource, "Guides");
            string destinationFolderGuides = Path.Combine(destinationFolderSetup, "Guides");

            if (Directory.Exists(sourceFolderGuides))
            {
                CopyFiles(sourceFolderGuides, destinationFolderGuides, Directory.GetFiles(sourceFolderGuides, "*.*", SearchOption.AllDirectories));
            }
        }

        private void CopyFiles(string sourceFolder, string destinationFolder, IEnumerable<string> files)
        {
            foreach (string file in files)
            {
                if (this.IsStopped())
                    break;

                string source = file;
                string destination = file.Replace(sourceFolder, destinationFolder);

                if (SetupMainFactory.GetInstance().Parameter.IsInstalled)
                {
                    if (!Directory.Exists(Path.GetDirectoryName(destination)))
                        Directory.CreateDirectory(Path.GetDirectoryName(destination));
                }

                this.IncrementProgress(destination);

                try
                {
                    if (SetupMainFactory.GetInstance().Parameter.IsInstalled)
                    {
                        if (Path.GetFileName(source) != "dotnetfx35.exe")
                        {
                            File.Copy(source, destination, true);

                            System.IO.FileInfo fi = new System.IO.FileInfo(destination);
                            fi.IsReadOnly = false;
                        }
                    }

                    this.AddUsedBy(destination);
                }
                catch
                {
                    this.DecrementProgress(destination);
                    throw;
                }
            }
        }

        protected override void UninstallArtefact(string artefactName)
        {
            if (File.Exists(artefactName))
                File.Delete(artefactName);

            if (Directory.Exists(Path.GetDirectoryName(artefactName)))
                PSE.Deployment.Util.File.DeleteEmptyDirectories(SetupMainFactory.GetInstance().Parameter.InstallationPath, Path.GetDirectoryName(artefactName));
        }
    }
}